#ifndef CLASSFACTORY_HPP
#define CLASSFACTORY_HPP

#include <iostream>
#include <map>
#include <memory>
#include <string>
#include "Function.hpp"

using namespace std;

class TimeIntergratorFactory
{
public:
    using CreateMethodCallback = TimeIntegrator *(*)(int n_, int p_, double T_, vector<double> value_);

private:
    using CallbackMap = map<string, CreateMethodCallback>;
    CallbackMap callbacks_;
    TimeIntergratorFactory() = default;
    TimeIntergratorFactory(const TimeIntergratorFactory &) = default;
    TimeIntergratorFactory &operator=(const TimeIntergratorFactory &) = default;
    ~TimeIntergratorFactory() = default;

public:
    static TimeIntergratorFactory &createFactory()
    {
        static TimeIntergratorFactory object;
        return object;
    }
    void registerProduct(const string &Id, TimeIntegrator *(*createFn)(int n_, int p_, double T_, vector<double> value_))
    {
        callbacks_[Id] = createFn;
    }

    TimeIntegrator *create(const string &ID, const int &n_, const int &p_, const double &T_, const vector<double> &value_)
    {
        auto it = callbacks_.find(ID);
        if (it != callbacks_.end())
        {
            return it->second(n_, p_, T_, value_);
        }
        return nullptr;
    }
};

// std::unique_ptr<method> createAdamsBashf(int steps = 100)
// {
//     return make_unique<AdamsBashforth>(steps);
// }

#endif